﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using TZReport_Model.DB;
using TZReport_Util.Extendsions;
using TZReport_Util.Model;

namespace TZRerport_Dal.Basic
{
    public class BaseDal<T> where T:class,new()
    {
        /// <summary>
        /// 注入DbContext
        /// </summary>
        public DbContext DbContext { get; set; }

        public BaseDal()
        {
            DbContext = new medical_lheyEntities();
        }

        public bool Add(T t)
        {
            DbContext.Set<T>().Add(t);
            return SaveChanges();
        }

        public bool AddList(List<T> list)
        {
            list.ForEach(a =>
            {
                DbContext.Set<T>().Add(a);
            });
            return SaveChanges();
        }

        public bool Up(T t)
        {
            DbContext.Entry<T>(t).State = EntityState.Modified;
            return SaveChanges();
        }

        public bool UpList(List<T> list)
        {
            list.ForEach(a =>
            {
                DbContext.Entry<T>(a).State = EntityState.Modified;
            });
            return SaveChanges();
        }

        public bool UpArray(params T[] ts)
        {
            ts.ToList().ForEach(a =>
            {
                if (a != null)
                {
                    DbContext.Entry<T>(a).State = EntityState.Modified;
                }

            });
            return SaveChanges();
        }

        public bool Del(T t)
        {
            //var req = HttpContext.Current.Request; // 当前线程
            //string remote_url = req.UserHostName + "/" + req.Path;
            //logHelper.Info("删除:" + JsonXmlUtils.SerializeObject(t) +$"请求接口:{remote_url}" +$"，删除时间:{DateTime.Now}");
            DbContext.Entry(t).State = EntityState.Deleted;
            return SaveChanges();
        }

        public bool DelList(List<T> list)
        {
            list.ForEach(a =>
            {
                DbContext.Entry(a).State = EntityState.Deleted;
            });


            return SaveChanges();
        }

        public IQueryable<T> Get(Expression<Func<T, bool>> whereLambda)
        {
            return DbContext.Set<T>().Where<T>(whereLambda);
        }

        public IQueryable<T> GetAsNoTracking(Expression<Func<T, bool>> whereLambda)
        {
            return DbContext.Set<T>().AsNoTracking().Where(whereLambda);
        }

        public IQueryable<T> GetPage<s>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> whereLambda, Expression<Func<T, s>> orderLambda, bool flag = true)
        {
            var temp = DbContext.Set<T>().AsNoTracking().Where<T>(whereLambda);
            totalCount = temp.Count<T>(); // 返回总记录数

            if (flag)
            {
                temp = temp.OrderBy<T, s>(orderLambda).Skip<T>((pageIndex - 1) * pageSize).Take<T>(pageSize);
            }
            else
            {
                temp = temp.OrderByDescending<T, s>(orderLambda).Skip<T>((pageIndex - 1) * pageSize).Take<T>(pageSize);
            }

            return temp;
        }

        public bool SaveChanges()
        {
            bool flag = false;
            try
            {
                if (DbContext.SaveChanges() > 0)
                    flag = !flag;
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            };

            return flag;
        }

        public int GetNextSort(Expression<Func<T, bool>> whereLambda, Expression<Func<T, int>> selector)
        {
            return GetMaxSort(whereLambda, selector) + 1;
        }

        public int GetMaxSort(Expression<Func<T, bool>> whereLambda, Expression<Func<T, int>> selector)
        {
            List<int> listSort = GetAsNoTracking(whereLambda).Select(selector).ToList();
            int maxSort = 0;

            if (listSort != null && listSort.Count > 0)
                maxSort = listSort.Max();

            return maxSort;
        }

        public string GetNextId(Expression<Func<T, string>> fnnc, bool year = false, bool month = false, bool day = false, int num = 7)
        {
            string maxId = DbContext.Set<T>().Max(fnnc);
            return GetMaxId(maxId, year, month, day, num);
        }


        public long GetNextId(Expression<Func<T, long>> fnnc)
        {
            long id = DbContext.Set<T>().Max(fnnc);
            id += 1;
            return id;
        }

        public int GetNextId(Expression<Func<T, int>> fnnc)
        {
            int id = DbContext.Set<T>().Max(fnnc);
            id += 1;
            return id;
        }

        public int GetMaxId(Expression<Func<T, string>> fnnc)
        {
            string id = DbContext.Set<T>().Max(fnnc);
            if (string.IsNullOrWhiteSpace(id))
                id = "0";
            return int.Parse(id);
        }

        public string GetMaxId(string maxId, bool year = false, bool month = false, bool day = false, int num = 7)
        {
            if (string.IsNullOrWhiteSpace(maxId))
                maxId = "0";

            string result = string.Empty;
            StringBuilder sb = new StringBuilder();
            if (year)
                sb.Append(DateTime.Now.Year.ToString());

            if (month)
                sb.Append(DateTime.Now.Month < 10 ? "0" + DateTime.Now.Month.ToString() : DateTime.Now.Month.ToString());

            if (day)
                sb.Append(DateTime.Now.Day < 10 ? "0" + DateTime.Now.Day.ToString() : DateTime.Now.Day.ToString());


            if (maxId == "0")
            {
                maxId = "1".PadLeft(num, '0');
            }
            else
            {
                if (maxId.Length > num)
                    maxId = maxId.Substring(maxId.Length - num);

                maxId = (long.Parse(maxId) + 1).ToString().PadLeft(num, '0');
            }

            sb.Append(maxId);
            result = sb.ToString();

            return result;
        }


        public List<K> GetSqlToList<K>(string sql)
        {
            return DbContext.Database.SqlQuery<K>(sql).ToList();
        }

        public int GetSqlToCount(string sql)
        {
            return DbContext.Database.SqlQuery<int>(sql).FirstOrDefault();
        }

    }
}
